import cookie from 'js-cookie';
class AppWebSocket {
    
    /**
     * 初始化时传入参数
     * @param {
     *  wsUrl 必传参数，ws链接路径
     *  callback 必传参数，ws消息回调函数
     *  data 选传参数，ws初始化时send参数
     * } params 
     */

    constructor(params) {
        this.params = params;
        this.params.token = cookie.get("USER_TOKEN");
        this.initSocket(params);
    }

    /**
     * websocket初始化调用函数
     * @param {Object} params 初始化传入参数，选填wsUrl
     */
    initSocket(params) {
        // let wsHost = '192.168.7.42:8088';
        let wsHost = location.hostname;
        if (wsHost == 'etl.test.cechealth.cn') {
            wsHost = 'bdp-nettywebsocket.test.cechealth.cn'
        } else {
            wsHost = 'bdp-nettywebsocket.dev.cechealth.cn:48017'
        }
        this.wsUrl = `ws://${wsHost}${params.wsUrl}`;
        this.lockReconnect = false;
        this.closeFlag = false;
        this.websock = new WebSocket(this.wsUrl);
        this.websock.onopen = this.websocketopen.bind(this);
        this.websock.onmessage = this.websocketonmessage.bind(this);
        this.websock.onclose = this.websocketclose.bind(this);
        this.websock.onerror = this.websocketerror.bind(this);
        //心跳检测
        this.heartCheck = {
            timeout: 10000,//10秒
            timeoutObj: null,
            serverTimeoutObj: null,
            reset: function() {
                clearTimeout(this.timeoutObj);
                clearTimeout(this.serverTimeoutObj);
                return this;
            },
            start: function(thisApp) {
                const _this = this;
                const _thisApp = thisApp;
                this.timeoutObj = setTimeout(() => {
                    //这里发送一个心跳，后端收到后，返回一个心跳消息，
                    //onmessage拿到返回的心跳就说明连接正常
                    _thisApp.socketSend({"action":"HEARTBEAT"});
                    _this.serverTimeoutObj = setTimeout(() => { //如果超过一定时间还没重置，说明后端主动断开了
                        _thisApp.socketClose(); //如果onclose会执行reconnect，我们执行socketClose就行了.如果直接执行reconnect 会触发onclose导致重连两次
                    }, _this.timeout)
                }, this.timeout)
            }
        }
    }

    //websocket open回调函数
    websocketopen() {
        this.params.data && this.socketSend(this.params.data);
        this.params.startHttp && this.params.startHttp();
        console.log("WebSocket建立连接",this.wsUrl);
        this.heartCheck.reset().start(this);
    }
    //websocket onmessage回调函数
    websocketonmessage(res) {
        this.heartCheck.reset().start(this);
        const data = JSON.parse(res.data);
        if (data.action === 'HEARTBEAT') return;
        this.params.callback(data);
    }
    //websocket close回调函数
    websocketclose(e) {
        console.log("WebSocket断开连接" + e.code);
    }
    //websocket error回调函数
    websocketerror(e) {
        console.log("WebSocket连接发生错误" + e.type);
        if (!this.closeFlag) {
            this.reconnect();
        }
    }

    //关闭链接
    socketClose() {
        this.closeFlag = true;
        this.socketSend({"action":"DISCONNECT"});
        this.heartCheck.reset();
        this.reconnectTimeOut && clearTimeout(this.reconnectTimeOut);
        this.websock.close();
    }

    // 异常重连
    reconnect() {
        if (this.lockReconnect) return;
        this.lockReconnect = true;
        //没连接上会一直重连，设置延迟避免请求过多
        this.reconnectTimeOut = setTimeout(() => {
            this.initSocket(this.params);
            this.lockReconnect = false;
        }, 2000);
    }

    //发送数据
    socketSend(data) {
        const _this = this;
        if (this.websock.readyState === this.websock.OPEN) {
            //若是ws开启状态
            this.websock.send(JSON.stringify(data));
        }else if (this.websock.readyState === this.websock.CONNECTING) {
            console.log('WebSocket正在开启中');
            // 若是 正在开启状态，则等待1s后重新调用
            setTimeout(function () {
                _this.socketSend(data);
            }, 1000);
        }else {
            console.log('WebSocket连接未开启，请先建立链接');
        }
    }
}
export default AppWebSocket;
